<div class="card" style="width: 100%; height: 100vh; display: flex; flex-direction: column;">
    <div id="graph-controls" style="margin: 10px; display: flex; justify-content: space-between;">
        <div>
            <button onclick="togglePhysics()" id="physics-toggle" class="btn btn-primary">Disable Physics</button>
            <button onclick="togglePhysicsSettings()" id="physics-settings-toggle" class="btn btn-outline-info">Physics Settings</button>
            <button onclick="stabilizeNetwork()" class="btn btn-secondary">Stabilize</button>
            <button onclick="toggleDarkMode()" id="theme-toggle" class="btn btn-info">Dark Mode</button>
            <button onclick="toggleFilterMenu()" id="filter-toggle" class="btn btn-outline-info">Show Filters</button>
            <button onclick="toggleLabels()" id="labels-toggle" class="btn btn-primary">Hide Labels</button>
            <button onclick="toggleStats()" id="stats-toggle" class="btn btn-outline-secondary">Stats</button>
        </div>
        <div>
            <span style="margin-right: 15px;"><strong>Edge Types:</strong></span>
            <span style="width: 30px; height: 2px; background-color: #666666; display: inline-block; margin-right: 5px;"></span>
            <span style="margin-right: 15px;">Extracted</span>
            <span style="width: 30px; height: 2px; border-top: 1px dashed #666666; display: inline-block; margin-right: 5px;"></span>
            <span>Inferred</span>
        </div>
    </div>
    
    <div id="stats-container" style="display: none; margin: 10px; padding: 15px; border: 1px solid #ddd; border-radius: 5px;">
        <h5>Graph Statistics</h5>
        <div style="display: flex; flex-wrap: wrap; gap: 20px;">
            <div class="stat-item">
                <strong>Nodes:</strong> <span id="stat-nodes">-</span>
            </div>
            <div class="stat-item">
                <strong>Edges:</strong> <span id="stat-edges">-</span>
            </div>
            <div class="stat-item">
                <strong>Extracted Edges:</strong> <span id="stat-extracted">-</span>
            </div>
            <div class="stat-item">
                <strong>Inferred Edges:</strong> <span id="stat-inferred">-</span>
            </div>
            <div class="stat-item">
                <strong>Communities:</strong> <span id="stat-communities">-</span>
            </div>
        </div>
    </div>
    
    <div id="physics-settings-container" style="display: none; margin: 10px; padding: 15px; border: 1px solid #ddd; border-radius: 5px;">
        <h5>Physics Settings</h5>
        <div style="display: flex; flex-wrap: wrap; gap: 15px;">
            <div style="min-width: 200px;">
                <label for="physics-solver">Solver</label>
                <select id="physics-solver" class="form-select" onchange="changeSolver()">
                    <option value="forceAtlas2Based">Force Atlas 2</option>
                    <option value="barnesHut">Barnes-Hut</option>
                    <option value="repulsion">Repulsion</option>
                </select>
            </div>
            
            <!-- Force Atlas 2 settings -->
            <div id="forceAtlas2Based-settings" class="solver-settings">
                <div class="setting-group">
                    <label for="fa2-gravConstant">Gravitational Constant</label>
                    <input type="range" id="fa2-gravConstant" min="-200" max="0" value="-50" class="form-range" oninput="updatePhysicsValue(this)">
                    <small class="value-display">-50</small>
                </div>
                <div class="setting-group">
                    <label for="fa2-centralGravity">Central Gravity</label>
                    <input type="range" id="fa2-centralGravity" min="0" max="1" step="0.01" value="0.01" class="form-range" oninput="updatePhysicsValue(this)">
                    <small class="value-display">0.01</small>
                </div>
                <div class="setting-group">
                    <label for="fa2-springLength">Spring Length</label>
                    <input type="range" id="fa2-springLength" min="10" max="500" value="100" class="form-range" oninput="updatePhysicsValue(this)">
                    <small class="value-display">100</small>
                </div>
                <div class="setting-group">
                    <label for="fa2-springConstant">Spring Constant</label>
                    <input type="range" id="fa2-springConstant" min="0" max="1" step="0.01" value="0.08" class="form-range" oninput="updatePhysicsValue(this)">
                    <small class="value-display">0.08</small>
                </div>
            </div>
            
            <!-- Barnes-Hut settings -->
            <div id="barnesHut-settings" class="solver-settings" style="display: none;">
                <div class="setting-group">
                    <label for="bh-gravConstant">Gravitational Constant</label>
                    <input type="range" id="bh-gravConstant" min="-30000" max="-1000" value="-8000" class="form-range" oninput="updatePhysicsValue(this)">
                    <small class="value-display">-8000</small>
                </div>
                <div class="setting-group">
                    <label for="bh-centralGravity">Central Gravity</label>
                    <input type="range" id="bh-centralGravity" min="0" max="1" step="0.01" value="0.3" class="form-range" oninput="updatePhysicsValue(this)">
                    <small class="value-display">0.3</small>
                </div>
                <div class="setting-group">
                    <label for="bh-springLength">Spring Length</label>
                    <input type="range" id="bh-springLength" min="10" max="500" value="250" class="form-range" oninput="updatePhysicsValue(this)">
                    <small class="value-display">250</small>
                </div>
                <div class="setting-group">
                    <label for="bh-springConstant">Spring Constant</label>
                    <input type="range" id="bh-springConstant" min="0" max="1" step="0.01" value="0.04" class="form-range" oninput="updatePhysicsValue(this)">
                    <small class="value-display">0.04</small>
                </div>
                <div class="setting-group">
                    <label for="bh-damping">Damping</label>
                    <input type="range" id="bh-damping" min="0" max="1" step="0.01" value="0.09" class="form-range" oninput="updatePhysicsValue(this)">
                    <small class="value-display">0.09</small>
                </div>
            </div>
            
            <!-- Repulsion settings -->
            <div id="repulsion-settings" class="solver-settings" style="display: none;">
                <div class="setting-group">
                    <label for="rep-nodeDistance">Node Distance</label>
                    <input type="range" id="rep-nodeDistance" min="10" max="300" value="100" class="form-range" oninput="updatePhysicsValue(this)">
                    <small class="value-display">100</small>
                </div>
                <div class="setting-group">
                    <label for="rep-centralGravity">Central Gravity</label>
                    <input type="range" id="rep-centralGravity" min="0" max="1" step="0.01" value="0.2" class="form-range" oninput="updatePhysicsValue(this)">
                    <small class="value-display">0.2</small>
                </div>
                <div class="setting-group">
                    <label for="rep-springLength">Spring Length</label>
                    <input type="range" id="rep-springLength" min="10" max="500" value="200" class="form-range" oninput="updatePhysicsValue(this)">
                    <small class="value-display">200</small>
                </div>
                <div class="setting-group">
                    <label for="rep-springStrength">Spring Strength</label>
                    <input type="range" id="rep-springStrength" min="0" max="1" step="0.01" value="0.05" class="form-range" oninput="updatePhysicsValue(this)">
                    <small class="value-display">0.05</small>
                </div>
                <div class="setting-group">
                    <label for="rep-damping">Damping</label>
                    <input type="range" id="rep-damping" min="0" max="1" step="0.01" value="0.09" class="form-range" oninput="updatePhysicsValue(this)">
                    <small class="value-display">0.09</small>
                </div>
            </div>
            
            <div style="margin-top: 15px;">
                <button onclick="applyPhysicsSettings()" class="btn btn-success">Apply Settings</button>
                <button onclick="resetPhysicsSettings()" class="btn btn-outline-secondary">Reset</button>
            </div>
        </div>
    </div>
    
    <div id="filter-menu-container" style="display: none; margin: 10px;">
        <div class="filter-row" style="display: flex; gap: 10px; margin-bottom: 10px;">
            <select id="node-select" class="form-select" style="flex: 1;" onchange="selectNode(this.value)">
                <option value="">Select a Node by ID</option>
            </select>
            <button onclick="resetSelection()" class="btn btn-primary">Reset Selection</button>
        </div>
        <div class="filter-row" style="display: flex; gap: 10px;">
            <select id="item-select" class="form-select" style="flex: 1;">
                <option value="">Select a network item</option>
                <option value="node">Nodes</option>
                <option value="edge">Edges</option>
            </select>
            <select id="property-select" class="form-select" style="flex: 1;">
                <option value="">Select a property</option>
            </select>
            <select id="value-select" class="form-select" style="flex: 1;">
                <option value="">Select value(s)</option>
            </select>
            <button onclick="filterSelection()" class="btn btn-primary">Filter</button>
            <button onclick="resetSelection()" class="btn btn-primary">Reset Selection</button>
        </div>
    </div>
    <div id="mynetwork" class="card-body" style="flex: 1;"></div>
    <div id="footer" style="position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%); padding: 5px 10px; text-align: center; font-size: 0.85rem; background-color: rgba(255, 255, 255, 0.7); border-radius: 4px; backdrop-filter: blur(2px); z-index: 100;">
        <a href="https://github.com/robert-mcdermott/ai-knowledge-graph" target="_blank" style="text-decoration: none; color: inherit;">
            Project: AI-Knowledge-Graph
        </a>
    </div>
</div>

<style id="theme-styles">
    /* Light mode (default) */
    body.light-mode {
        background-color: white;
        color: black;
        margin: 0;
        padding: 0;
        height: 100vh;
        overflow: hidden;
    }
    
    /* Dark mode */
    body.dark-mode {
        background-color: #121212;
        color: #e0e0e0;
        margin: 0;
        padding: 0;
        height: 100vh;
        overflow: hidden;
    }
    
    /* Full height layout styling */
    html, body {
        height: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
    }
    
    .card {
        border-radius: 0;
        margin: 0;
        padding: 0;
        overflow: hidden;
    }
    
    .card-body {
        padding: 0;
        overflow: hidden;
    }
    
    body.dark-mode .card {
        background-color: #1e1e1e;
        border-color: #333;
    }
    
    body.dark-mode .btn {
        border-color: #444;
    }
    
    body.dark-mode #mynetwork {
        border-color: #333;
        background-color: #000000;
    }
    
    body.dark-mode .form-select {
        background-color: #333;
        color: #e0e0e0;
        border-color: #555;
    }
    
    /* Physics settings styles */
    #physics-settings-container {
        background-color: #f8f9fa;
    }
    
    body.dark-mode #physics-settings-container {
        background-color: #2d2d2d;
        border-color: #444;
    }
    
    .setting-group {
        margin-bottom: 12px;
        min-width: 200px;
    }
    
    .setting-group label {
        display: block;
        margin-bottom: 3px;
        font-size: 14px;
    }
    
    .setting-group .value-display {
        display: inline-block;
        min-width: 40px;
        text-align: right;
    }
    
    .solver-settings {
        display: flex;
        flex-wrap: wrap;
        gap: 20px;
    }
    
    /* Node label colors - strong selectors to override vis.js styles */
    .vis-network .vis-node {
        font-family: Tahoma, sans-serif;
    }
    
    /* Strongest selectors for node text color */
    .vis-network text,
    .vis-network text.vis-text,
    .vis-network .vis-node text,
    .vis-network text[class*="vis-"],
    .vis-network .vis-label text {
        fill: #000000 !important;
        stroke: none !important;
        color: #000000 !important;
    }
    
    body.dark-mode .vis-network text,
    body.dark-mode .vis-network text.vis-text,
    body.dark-mode .vis-network .vis-node text,
    body.dark-mode .vis-network text[class*="vis-"],
    body.dark-mode .vis-network .vis-label text {
        fill: #ffffff !important;
        stroke: none !important;
        color: #ffffff !important;
    }
    
    /* Stats container styles */
    #stats-container {
        background-color: #f8f9fa;
        border-color: #ddd;
        color: #212529;
    }
    
    body.dark-mode #stats-container {
        background-color: #1e1e1e;
        border-color: #444;
        color: #e0e0e0;
    }
    
    /* Footer styles */
    #footer {
        color: #6c757d;
        box-shadow: 0 1px 3px rgba(0,0,0,0.12);
    }
    
    body.dark-mode #footer {
        background-color: rgba(30, 30, 30, 0.7) !important;
        color: #adb5bd;
    }
</style>

<script>
// Helper function to ensure node text colors are correct
function updateNodeTextColors(color) {
    if (!network || !network.body || !network.body.data || !network.body.data.nodes) return;
    
    try {
        // Update through vis.js API
        const nodeIds = network.body.data.nodes.getIds();
        const updates = nodeIds.map(nodeId => ({
            id: nodeId,
            font: { 
                color: color,
                strokeWidth: 0 
            }
        }));
        network.body.data.nodes.update(updates);
        
        // Direct manipulation of SVG text elements as fallback
        setTimeout(() => {
            try {
                const textElements = document.querySelectorAll('.vis-network text');
                textElements.forEach(el => {
                    el.style.fill = color;
                    el.setAttribute('fill', color);
                });
            } catch (e) {
                console.error('Error directly manipulating SVG:', e);
            }
        }, 100);
    } catch (e) {
        console.error('Error updating node colors:', e);
    }
}

// Function to resize the network container when menus open/close
function resizeNetwork() {
    // Allow a brief moment for DOM updates
    setTimeout(function() {
        // Resize the network to fit the container
        if (window.network) {
            network.redraw();
            network.fit();
        }
    }, 100);
}

// Global variable to track label state
let labelsVisible = true;

// Function to toggle node and edge labels
function toggleLabels() {
    const toggleBtn = document.getElementById('labels-toggle');
    
    // Toggle the state
    labelsVisible = !labelsVisible;
    
    if (labelsVisible) {
        // Show labels
        network.setOptions({
            nodes: {
                font: { 
                    size: 14,
                    color: document.body.classList.contains('dark-mode') ? '#ffffff' : '#000000'
                }
            },
            edges: {
                font: { 
                    size: 12,
                    color: document.body.classList.contains('dark-mode') ? '#ffdd00' : '#000000'
                }
            }
        });
        toggleBtn.textContent = 'Hide Labels';
        toggleBtn.classList.remove('btn-outline-primary');
        toggleBtn.classList.add('btn-primary');
    } else {
        // Hide labels
        network.setOptions({
            nodes: {
                font: { size: 0 }
            },
            edges: {
                font: { size: 0 }
            }
        });
        toggleBtn.textContent = 'Show Labels';
        toggleBtn.classList.remove('btn-primary');
        toggleBtn.classList.add('btn-outline-primary');
    }
}

function togglePhysics() {
    const toggleBtn = document.getElementById('physics-toggle');
    
    if (network.physics.options.enabled) {
        network.physics.stopSimulation();
        network.setOptions({physics: {enabled: false}});
        toggleBtn.textContent = 'Enable Physics';
        toggleBtn.classList.remove('btn-primary');
        toggleBtn.classList.add('btn-outline-primary');
    } else {
        network.setOptions({physics: {enabled: true}});
        network.startSimulation();
        toggleBtn.textContent = 'Disable Physics';
        toggleBtn.classList.remove('btn-outline-primary');
        toggleBtn.classList.add('btn-primary');
    }
}

function togglePhysicsSettings() {
    const container = document.getElementById('physics-settings-container');
    const button = document.getElementById('physics-settings-toggle');
    
    if (container.style.display === 'none') {
        container.style.display = 'block';
        button.textContent = 'Hide Physics Settings';
        button.classList.remove('btn-outline-info');
        button.classList.add('btn-info');
    } else {
        container.style.display = 'none';
        button.textContent = 'Physics Settings';
        button.classList.remove('btn-info');
        button.classList.add('btn-outline-info');
    }
    
    // Resize network when toggling menu
    resizeNetwork();
}

function changeSolver() {
    const selectedSolver = document.getElementById('physics-solver').value;
    
    // Hide all solver setting sections
    document.querySelectorAll('.solver-settings').forEach(el => {
        el.style.display = 'none';
    });
    
    // Show the selected solver settings
    document.getElementById(`${selectedSolver}-settings`).style.display = 'flex';
}

function updatePhysicsValue(input) {
    // Update the display value next to the slider
    const valueDisplay = input.nextElementSibling;
    valueDisplay.textContent = input.value;
}

function applyPhysicsSettings() {
    const solver = document.getElementById('physics-solver').value;
    let physicsOptions = { solver: solver };
    
    // Get the settings for the selected solver
    if (solver === 'forceAtlas2Based') {
        physicsOptions.forceAtlas2Based = {
            gravitationalConstant: parseFloat(document.getElementById('fa2-gravConstant').value),
            centralGravity: parseFloat(document.getElementById('fa2-centralGravity').value),
            springLength: parseFloat(document.getElementById('fa2-springLength').value),
            springConstant: parseFloat(document.getElementById('fa2-springConstant').value)
        };
    } else if (solver === 'barnesHut') {
        physicsOptions.barnesHut = {
            gravitationalConstant: parseFloat(document.getElementById('bh-gravConstant').value),
            centralGravity: parseFloat(document.getElementById('bh-centralGravity').value),
            springLength: parseFloat(document.getElementById('bh-springLength').value),
            springConstant: parseFloat(document.getElementById('bh-springConstant').value),
            damping: parseFloat(document.getElementById('bh-damping').value)
        };
    } else if (solver === 'repulsion') {
        physicsOptions.repulsion = {
            nodeDistance: parseFloat(document.getElementById('rep-nodeDistance').value),
            centralGravity: parseFloat(document.getElementById('rep-centralGravity').value),
            springLength: parseFloat(document.getElementById('rep-springLength').value),
            springConstant: parseFloat(document.getElementById('rep-springStrength').value),
            damping: parseFloat(document.getElementById('rep-damping').value)
        };
    }
    
    // Apply the settings
    network.setOptions({ physics: physicsOptions });
    
    // Restart the simulation
    network.startSimulation();
    
    // Update the physics toggle button
    const toggleBtn = document.getElementById('physics-toggle');
    toggleBtn.textContent = 'Disable Physics';
    toggleBtn.classList.remove('btn-outline-primary');
    toggleBtn.classList.add('btn-primary');
    
    console.log('Applied physics settings:', physicsOptions);
}

function resetPhysicsSettings() {
    // Reset Force Atlas 2 settings
    document.getElementById('fa2-gravConstant').value = -50;
    document.getElementById('fa2-centralGravity').value = 0.01;
    document.getElementById('fa2-springLength').value = 100;
    document.getElementById('fa2-springConstant').value = 0.08;
    
    // Reset Barnes-Hut settings
    document.getElementById('bh-gravConstant').value = -8000;
    document.getElementById('bh-centralGravity').value = 0.3;
    document.getElementById('bh-springLength').value = 250;
    document.getElementById('bh-springConstant').value = 0.04;
    document.getElementById('bh-damping').value = 0.09;
    
    // Reset Repulsion settings
    document.getElementById('rep-nodeDistance').value = 100;
    document.getElementById('rep-centralGravity').value = 0.2;
    document.getElementById('rep-springLength').value = 200;
    document.getElementById('rep-springStrength').value = 0.05;
    document.getElementById('rep-damping').value = 0.09;
    
    // Update all displayed values
    document.querySelectorAll('.form-range').forEach(input => {
        const valueDisplay = input.nextElementSibling;
        valueDisplay.textContent = input.value;
    });
    
    // Reset to Force Atlas 2
    document.getElementById('physics-solver').value = 'forceAtlas2Based';
    changeSolver();
    
    // Apply the default settings
    applyPhysicsSettings();
}

function stabilizeNetwork() {
    network.stabilize(100);
}

function toggleDarkMode() {
    const body = document.body;
    const toggleBtn = document.getElementById('theme-toggle');
    
    if (body.classList.contains('dark-mode')) {
        // Switch to light mode
        body.classList.remove('dark-mode');
        body.classList.add('light-mode');
        toggleBtn.textContent = 'Dark Mode';
        
        // Update network with light mode settings
        network.setOptions({
            background: {
                color: 'white'
            },
            nodes: {
                font: {
                    color: '#000000',
                    strokeWidth: 0,
                    size: labelsVisible ? 14 : 0
                }
            },
            edges: {
                font: {
                    color: '#000000',
                    strokeWidth: 4,
                    size: labelsVisible ? 12 : 0
                }
            }
        });
        
        // Force correct node text color
        updateNodeTextColors('#000000');
    } else {
        // Switch to dark mode
        body.classList.remove('light-mode');
        body.classList.add('dark-mode');
        toggleBtn.textContent = 'Light Mode';
        
        // Update network with dark mode settings
        network.setOptions({
            background: {
                color: '#1e1e1e'
            },
            nodes: {
                font: {
                    color: '#ffffff',
                    strokeWidth: 0,
                    size: labelsVisible ? 14 : 0
                }
            },
            edges: {
                font: {
                    color: '#ffdd00',  // Yellow color for edge text
                    strokeWidth: 0,    // Remove text border/stroke in dark mode
                    size: labelsVisible ? 12 : 0
                }
            }
        });
        
        // Force correct node text color
        updateNodeTextColors('#ffffff');
    }
}

function toggleFilterMenu() {
    const container = document.getElementById('filter-menu-container');
    const button = document.getElementById('filter-toggle');
    
    if (container.style.display === 'none') {
        container.style.display = 'block';
        button.textContent = 'Hide Filters';
        button.classList.remove('btn-outline-info');
        button.classList.add('btn-info');
        populateFilterOptions();
    } else {
        container.style.display = 'none';
        button.textContent = 'Show Filters';
        button.classList.remove('btn-info');
        button.classList.add('btn-outline-info');
    }
    
    // Resize network when toggling menu
    resizeNetwork();
}

function populateFilterOptions() {
    // Get all node IDs for the node selector
    const nodeSelect = document.getElementById('node-select');
    // Clear existing options except the first one
    while (nodeSelect.options.length > 1) {
        nodeSelect.remove(1);
    }
    
    // Add all nodes to the select
    const nodeIds = network.body.data.nodes.getIds();
    nodeIds.forEach(nodeId => {
        const option = document.createElement('option');
        option.value = nodeId;
        option.text = nodeId;
        nodeSelect.appendChild(option);
    });
    
    // Also handle the filter property and value selectors
    const itemSelect = document.getElementById('item-select');
    const propertySelect = document.getElementById('property-select');
    const valueSelect = document.getElementById('value-select');
    
    // Clear previous values
    while (propertySelect.options.length > 1) propertySelect.remove(1);
    while (valueSelect.options.length > 1) valueSelect.remove(1);
    
    // When item type changes, update available properties
    itemSelect.onchange = function() {
        const selectedItem = itemSelect.value;
        
        // Clear previous property options
        while (propertySelect.options.length > 1) propertySelect.remove(1);
        while (valueSelect.options.length > 1) valueSelect.remove(1);
        
        if (selectedItem === 'node') {
            // Add node properties
            const nodeProperties = ['id', 'label', 'color', 'title', 'community'];
            nodeProperties.forEach(prop => {
                const option = document.createElement('option');
                option.value = prop;
                option.text = prop;
                propertySelect.appendChild(option);
            });
        } else if (selectedItem === 'edge') {
            // Add edge properties
            const edgeProperties = ['from', 'to', 'label', 'title'];
            edgeProperties.forEach(prop => {
                const option = document.createElement('option');
                option.value = prop;
                option.text = prop;
                propertySelect.appendChild(option);
            });
        }
    };
    
    // When property changes, populate possible values
    propertySelect.onchange = function() {
        const selectedItem = itemSelect.value;
        const selectedProperty = propertySelect.value;
        
        if (!selectedItem || !selectedProperty) return;
        
        // Clear previous value options
        while (valueSelect.options.length > 1) valueSelect.remove(1);
        
        const values = new Set();
        
        if (selectedItem === 'node') {
            // Get all unique values for the selected node property
            const nodes = network.body.data.nodes.get();
            nodes.forEach(node => {
                if (node[selectedProperty] !== undefined) {
                    // Handle special case for community in node color
                    if (selectedProperty === 'community') {
                        // Extract community from node color (simplified approach)
                        const colorIndex = ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00', '#ffff33', '#a65628', '#f781bf'].indexOf(node.color);
                        if (colorIndex >= 0) {
                            values.add(colorIndex.toString());
                        }
                    } else {
                        values.add(node[selectedProperty].toString());
                    }
                }
            });
        } else if (selectedItem === 'edge') {
            // Get all unique values for the selected edge property
            const edges = network.body.data.edges.get();
            edges.forEach(edge => {
                if (edge[selectedProperty] !== undefined) {
                    values.add(edge[selectedProperty].toString());
                }
            });
        }
        
        // Add values to select
        Array.from(values).sort().forEach(value => {
            const option = document.createElement('option');
            option.value = value;
            option.text = value;
            valueSelect.appendChild(option);
        });
    };
}

function filterSelection() {
    const itemType = document.getElementById('item-select').value;
    const property = document.getElementById('property-select').value;
    const value = document.getElementById('value-select').value;
    
    if (!itemType || !property || !value) {
        alert('Please select all filter criteria');
        return;
    }
    
    try {
        const nodesToShow = [];
        const edgesToShow = [];
        
        // If we're filtering nodes directly
        if (itemType === 'node') {
            const nodes = network.body.data.nodes.get();
            nodes.forEach(node => {
                let match = false;
                
                // Handle special case for community
                if (property === 'community') {
                    const colorIndex = ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00', '#ffff33', '#a65628', '#f781bf'].indexOf(node.color);
                    match = colorIndex.toString() === value;
                } else {
                    match = node[property] && node[property].toString() === value;
                }
                
                if (match) {
                    nodesToShow.push(node.id);
                    
                    // Also include connected edges
                    const connectedEdges = network.getConnectedEdges(node.id);
                    connectedEdges.forEach(edgeId => {
                        const edge = network.body.data.edges.get(edgeId);
                        if (nodesToShow.includes(edge.from) || nodesToShow.includes(edge.to)) {
                            edgesToShow.push(edgeId);
                        }
                    });
                }
            });
        }
        // If we're filtering edges
        else if (itemType === 'edge') {
            const edges = network.body.data.edges.get();
            edges.forEach(edge => {
                if (edge[property] && edge[property].toString() === value) {
                    edgesToShow.push(edge.id);
                    // Include connected nodes
                    nodesToShow.push(edge.from);
                    nodesToShow.push(edge.to);
                }
            });
        }
        
        // Apply the filter by hiding all nodes/edges except our selection
        const allNodes = network.body.data.nodes.get();
        const allEdges = network.body.data.edges.get();
        
        const nodeUpdates = [];
        const edgeUpdates = [];
        
        allNodes.forEach(node => {
            nodeUpdates.push({
                id: node.id,
                hidden: !nodesToShow.includes(node.id)
            });
        });
        
        allEdges.forEach(edge => {
            edgeUpdates.push({
                id: edge.id,
                hidden: !edgesToShow.includes(edge.id)
            });
        });
        
        // Apply updates
        network.body.data.nodes.update(nodeUpdates);
        network.body.data.edges.update(edgeUpdates);
        
        console.log(`Filtered to show ${nodesToShow.length} nodes and ${edgesToShow.length} edges`);
    } catch (error) {
        console.error('Error applying filter:', error);
        alert('Error applying filter. See console for details.');
    }
}

function resetSelection() {
    // Clear any selection
    network.unselectAll();
    
    // Reset the visibility of all nodes and edges
    const allNodes = network.body.data.nodes.get();
    const allEdges = network.body.data.edges.get();
    
    const nodeUpdates = allNodes.map(node => ({
        id: node.id,
        hidden: false
    }));
    
    const edgeUpdates = allEdges.map(edge => ({
        id: edge.id,
        hidden: false
    }));
    
    // Apply updates
    network.body.data.nodes.update(nodeUpdates);
    network.body.data.edges.update(edgeUpdates);
    
    console.log('Reset all filters');
}

function selectNode(nodeId) {
    if (!nodeId) {
        resetSelection();
        return;
    }
    
    try {
        // Get the selected node
        const node = network.body.data.nodes.get(nodeId);
        if (!node) return;
        
        // Focus on the node
        network.selectNodes([nodeId]);
        network.focus(nodeId, {
            scale: 1.5,
            animation: {
                duration: 1000,
                easingFunction: "easeInOutQuad"
            }
        });
        
        console.log(`Selected node: ${nodeId}`);
    } catch (error) {
        console.error('Error selecting node:', error);
    }
}

// Set initial theme class
document.body.classList.add('light-mode');

// Rewritten approach for node text colors
(function() {
    // Function to handle network initialization
    function initializeNetwork() {
        if (!window.network) return false;
        
        console.log("Setting initial network options");
        
        // Force node text color settings
        network.setOptions({
            nodes: {
                font: {
                    color: '#000000',
                    face: 'Tahoma',
                    strokeWidth: 0
                }
            }
        });
        
        // Set physics toggle button state based on network physics state
        const physicsToggleBtn = document.getElementById('physics-toggle');
        if (physicsToggleBtn) {
            if (network.physics.options.enabled) {
                physicsToggleBtn.textContent = 'Disable Physics';
                physicsToggleBtn.classList.remove('btn-outline-primary');
                physicsToggleBtn.classList.add('btn-primary');
            } else {
                physicsToggleBtn.textContent = 'Enable Physics';
                physicsToggleBtn.classList.remove('btn-primary');
                physicsToggleBtn.classList.add('btn-outline-primary');
            }
        }
        
        // Apply direct SVG manipulation
        const textElements = document.querySelectorAll('.vis-network text');
        textElements.forEach(el => {
            el.style.fill = '#000000';
            el.setAttribute('fill', '#000000');
            el.style.stroke = 'none';
            el.setAttribute('stroke', 'none');
        });
        
        return true;
    }
    
    // Add a style tag to force node colors
    const style = document.createElement('style');
    style.textContent = `
        .vis-network text { fill: #000000 !important; color: #000000 !important; }
        body.dark-mode .vis-network text { fill: #ffffff !important; color: #ffffff !important; }
    `;
    document.head.appendChild(style);
    
    // Try to initialize immediately
    if (initializeNetwork()) {
        console.log("Network initialized immediately");
    }
    
    // DOMContentLoaded approach
    document.addEventListener('DOMContentLoaded', function() {
        // Check for network repeatedly
        const networkCheck = setInterval(() => {
            if (initializeNetwork()) {
                console.log("Network initialized via interval");
                clearInterval(networkCheck);
            }
        }, 50);
        
        // Backup timeout approaches
        for (let i = 1; i <= 20; i++) {
            setTimeout(() => {
                if (window.network) {
                    console.log(`Applying color fix at ${i*100}ms`);
                    initializeNetwork();
                    updateNodeTextColors('#000000');
                }
            }, i * 100);
        }
    });
    
    // Add mutation observer to catch when network is added to DOM
    const observer = new MutationObserver((mutations) => {
        for (const mutation of mutations) {
            if (mutation.addedNodes.length) {
                if (window.network) {
                    console.log("Network detected via mutation observer");
                    initializeNetwork();
                    updateNodeTextColors('#000000');
                    observer.disconnect();
                    break;
                }
            }
        }
    });
    
    // Start observing
    observer.observe(document.body, { childList: true, subtree: true });
})();

// Original network stabilization listener (keep this)
network.once("stabilizationIterationsDone", function() {
    // Auto-stabilize after initial load
    setTimeout(function() {
        // Don't stop simulation since physics is now on by default
        
        // Set physics toggle button state
        const physicsToggleBtn = document.getElementById('physics-toggle');
        if (physicsToggleBtn) {
            physicsToggleBtn.textContent = 'Disable Physics';
            physicsToggleBtn.classList.remove('btn-outline-primary');
            physicsToggleBtn.classList.add('btn-primary');
        }
        
        // Make sure the network fits the available space
        network.fit();
    }, 1000);
    
    // Ensure node and edge text colors are set correctly for initial light mode
    network.setOptions({
        nodes: {
            font: {
                color: '#000000',
                face: 'Tahoma',
                strokeWidth: 0,
                size: 14
            }
        },
        edges: {
            font: {
                color: '#000000',
                strokeWidth: 4,  // Default border for light mode
                size: 12
            }
        }
    });
    
    // Fix any nodes that might have incorrect font color
    updateNodeTextColors('#000000');
    
    console.log("Network stabilization complete");
});

// Handle window resize events to make sure the network always fits
window.addEventListener('resize', function() {
    if (window.network) {
        network.fit();
    }
});

function toggleStats() {
    const container = document.getElementById('stats-container');
    const button = document.getElementById('stats-toggle');
    
    if (container.style.display === 'none') {
        container.style.display = 'block';
        button.textContent = 'Hide Stats';
        button.classList.remove('btn-outline-secondary');
        button.classList.add('btn-secondary');
        
        // Update statistics
        updateGraphStats();
    } else {
        container.style.display = 'none';
        button.textContent = 'Stats';
        button.classList.remove('btn-secondary');
        button.classList.add('btn-outline-secondary');
    }
    
    // Resize network when toggling menu
    resizeNetwork();
}

function updateGraphStats() {
    if (!network || !network.body || !network.body.data) return;
    
    try {
        // Count nodes
        const totalNodes = network.body.data.nodes.length;
        document.getElementById('stat-nodes').textContent = totalNodes;
        
        // Count edges
        const totalEdges = network.body.data.edges.length;
        document.getElementById('stat-edges').textContent = totalEdges;
        
        // Count edge types (assuming a property on the edge indicating if it's inferred)
        let extractedEdges = 0;
        let inferredEdges = 0;
        
        network.body.data.edges.forEach(edge => {
            // This logic might need to be adjusted based on how your edges are marked
            if (edge.dashes === true || (Array.isArray(edge.dashes) && edge.dashes.length > 0)) {
                inferredEdges++;
            } else {
                extractedEdges++;
            }
        });
        
        document.getElementById('stat-extracted').textContent = extractedEdges;
        document.getElementById('stat-inferred').textContent = inferredEdges;
        
        // Count communities (based on node colors)
        const communities = new Set();
        network.body.data.nodes.forEach(node => {
            if (node.color) {
                communities.add(node.color);
            }
        });
        
        document.getElementById('stat-communities').textContent = communities.size;
    } catch (error) {
        console.error('Error updating graph statistics:', error);
    }
}

// Update stats when network is stabilized
network.once("stabilizationIterationsDone", function() {
    // Add statistics update
    updateGraphStats();
    
    // Original code continues...
    setTimeout(function() {
        // Don't stop simulation since physics is now on by default
        
        // Set physics toggle button state
        const physicsToggleBtn = document.getElementById('physics-toggle');
        if (physicsToggleBtn) {
            physicsToggleBtn.textContent = 'Disable Physics';
            physicsToggleBtn.classList.remove('btn-outline-primary');
            physicsToggleBtn.classList.add('btn-primary');
        }
        
        // Make sure the network fits the available space
        network.fit();
    }, 1000);
    
    // Ensure node and edge text colors are set correctly for initial light mode
    network.setOptions({
        nodes: {
            font: {
                color: '#000000',
                face: 'Tahoma',
                strokeWidth: 0,
                size: 14
            }
        },
        edges: {
            font: {
                color: '#000000',
                strokeWidth: 4,  // Default border for light mode
                size: 12
            }
        }
    });
    
    // Fix any nodes that might have incorrect font color
    updateNodeTextColors('#000000');
    
    console.log("Network stabilization complete");
});
</script> 